/*
 * Interpolate.js library agnostic attribute interpolation, preserving measure
 * Public Domain - please submit patches to prozacgod@gmail.com
 */
function accel_interpolator(interpolator) {
	return function(position, start, end) {
		return interpolator((2.73468*position*position*position) - (4.10202*position*position) + (2.37254*position) - 0.00259879, start, end);
	}
}

function quarter_sine_interpolator(interpolator) {
	return function(position, start, end) {
		return interpolator(Math.sin(position * 1.570795), start, end);
	}
}

function linear_interpolator(position, start, end) {
	if (start > end) {
		return start - (position * (start - end));
	} else if (start < end) {
		return start + (position * (end - start));
	} else {
		return start;
	}
}

function Interpolate(start, end, interpolator, interpolators) {
	if (!interpolators)
		interpolators = {};
	
	var properties = {};
	
	for(var property in end) {
		var interpolator = interpolators[property] ? interpolators[property] : (interpolator ? interpolator : linear_interpolator);
		
		var end_s = end[property]+'';
		var end_value = parseFloat(end_s);
		var end_measure = "";
		if ((""+end_value).length != end_s.length)
			end_measure = end_s.substr((""+end_value).length, end_s.length);
							
		var start_s = start[property]+'';
		var start_value = parseFloat(start_s);
		var start_measure = "";
		if ((""+start_value).length != start_s.length)
			start_measure = start_s.substr((""+start_value).length, start_s.length);
					
		properties[property] = {'start': start_value, 'start_measure': start_measure, 'end': end_value, 'end_measure':end_measure, 'interpolator': interpolator};
	}
	delete default_interpolator;
	delete interpolators;
	return function(position) {
		if (position > 1)
			position = 1;
		if (position < 0)
			position = 0;
		var result = {};
		for (var prop in properties) {
			var measure = (position == 0) ? properties[prop].start_measure : properties[prop].end_measure;
			result[prop] = properties[prop].interpolator(position, properties[prop].start, properties[prop].end) + measure;
		}
		return result;
	}
}
